package com.ty.framework.exception;

import com.ty.common.exception.SKYException;
import com.ty.common.utils.R;
import java.util.HashMap;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpStatus;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;

/**
 * @author 天宇宇宇宇宇 @Data 2020/12/14 18:45
 *     <p>集中处理所有异常
 */
@RestControllerAdvice
@Slf4j
public class SKYExceptionHandler {

  /**
   * 处理自定义异常
   *
   * @param e
   * @return
   */
  @ExceptionHandler(value = SKYException.class)
  public R handlerSKYException(SKYException e) {
    R r = new R();
    r.put("code", e.getCode());
    r.put("msg", e.getMsg());
    return r;
  }

  /**
   * 404异常
   *
   * @param e
   * @return
   */
  @ExceptionHandler(value = NoHandlerFoundException.class)
  public R handlerNoHandlerFoundException(Exception e) {
    return R.error(HttpStatus.SC_NOT_FOUND, "路径不存在，请检查路径是否正确");
  }

  /**
   * 重复插入异常
   *
   * @param e
   * @return
   */
  @ExceptionHandler(value = DuplicateKeyException.class)
  public R handlerDuplicateKeyException(DuplicateKeyException e) {
    log.error("数据重复插入异常:{}, 异常类型:{}", e.getMessage(), e);
    return R.error("数据库已经存在该条记录");
  }

  /**
   * 无权限异常
   *
   * @param e
   * @return
   */
  // TODO 后续加上权限框架再搞
  /* @ExceptionHandler(AuthorizationException.class)
  public R handleAuthorizationException(AuthorizationException e){
      logger.error(e.getMessage(), e);
      return R.error("没有权限，请联系管理员授权");
  }*/

  /**
   * 自定义校验数据异常
   *
   * @param e
   * @return
   */
  @ExceptionHandler(value = MethodArgumentNotValidException.class)
  public R handleVaildException(MethodArgumentNotValidException e) {
    log.error("数据校验异常:{}, 异常类型: {}", e.getMessage(), e.getClass());
    BindingResult bindingResult = e.getBindingResult();
    Map<String, String> errorMap = new HashMap<>();
    bindingResult
        .getFieldErrors()
        .forEach(
            fieldError -> {
              errorMap.put(fieldError.getField(), fieldError.getDefaultMessage());
            });
    return R.error(HttpStatus.SC_UNAUTHORIZED, "数据校验异常").put(errorMap);
  }

  /**
   * 其他异常
   *
   * @param throwable
   * @return
   */
  @ResponseStatus()
  @ExceptionHandler(value = Throwable.class)
  public R handleException(Throwable throwable) {
    return R.error(throwable.getMessage());
  }
}
